package io.afu.baseframework.annotations.impls;



import io.afu.baseframework.components.AsyncLogger;
import io.afu.baseframework.utils.CommonUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class BSLogImpl {

    private final Logger logger = LoggerFactory.getLogger(getClass());


    @Autowired
    AsyncLogger asyncLogger;

    @Pointcut(value = "@annotation(io.afu.baseframework.annotations.BSLog)")
    public void cutBussinessLog(){

    }

    @Around("cutBussinessLog()")
    public Object recordSysLog(ProceedingJoinPoint point) throws Throwable {
        //先执行业务
        String uniqueCode = CommonUtils.getOrderNo();
        // 先记录入参以防出错,相比些许性能的影响，出入参才是关键。
        handleBefore(uniqueCode,point);
        Object result = point.proceed();
        try {
            handAfter(uniqueCode,result);
        } catch (Exception e) {
            logger.error("日志记录出错!", e);
        }
        return result;
    }

    private void handAfter(String uniqueCode,Object result) {
        // 开始记录后续的内容。
        asyncLogger.budinessLog(uniqueCode,result);
    }

    private void handleBefore(String uniqueCode,ProceedingJoinPoint point) throws NoSuchMethodException {
        //获取拦截的方法名
        Signature sig = point.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Object target = point.getTarget();
        Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        String methodName = currentMethod.getName();
        //获取拦截方法的参数
        String className = point.getTarget().getClass().getName();
        Object[] params = point.getArgs();
        asyncLogger.businessLog(uniqueCode,className, methodName, params);
    }





    private void handle(ProceedingJoinPoint point,Object result) throws Exception {
        //获取拦截的方法名
        Signature sig = point.getSignature();
        MethodSignature msig = null;
        if (!(sig instanceof MethodSignature)) {
            throw new IllegalArgumentException("该注解只能用于方法");
        }
        msig = (MethodSignature) sig;
        Object target = point.getTarget();
        Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
        String methodName = currentMethod.getName();
        //获取拦截方法的参数
        String className = point.getTarget().getClass().getName();
        Object[] params = point.getArgs();
        asyncLogger.businessLog(className, methodName, params, result);
    }





}
